(*
	videoPlayers() -- Return a list of the valid videodisc player names.

	To compile and link this file using Macintosh Programmer's Workshop,

		pascal -w videoPlayers.p

		link -m ENTRYPOINT -o HyperCommands -rt XFCN=8003 -sn Main=videoPlayers ¶
			videoPlayers.p.o "{MPW}"Libraries:interface.o "{MPW}"PLibraries:PasLib.o

	Copyright © 1988 Apple Computer, Inc.

	2/88 - Initial coding by Harry R. Chesley.
*)

{$R-}

{$S videoPlayers } 	{ Segment name must be the same as the command name. }

unit DummyUnit;

interface

uses MemTypes, QuickDraw, OSIntf, ToolIntf, HyperXCmd;

procedure EntryPoint(paramPtr: XCmdPtr);
	
implementation

type

Str31 = String[31];

procedure videoPlayers(paramPtr: XCmdPtr); forward;

procedure EntryPoint(paramPtr: XCmdPtr);

	begin
		videoPlayers(paramPtr);
	end;

procedure videoPlayers(paramPtr: XCmdPtr);

	var resHandle: Handle;			{ Driver resource handle. }
		resID: integer;					{ Driver resource ID. }
		resType: ResType;			{ Driver resource type. }
		resName: str255;				{ Driver resource name. }
		i: integer;
		thePlayers: Handle;			{ List of players. }
		oldSize, nextNameOffset, playersSize: longInt;
		newName: str255;
		playerXFCN: str255;		{ Player driver name. }
		theNames: Handle;			{ List of names. }
		p, p2: Ptr;
		lastChar: SignedByte;
		str: str255;

	{$I XCmdGlue.inc}

	procedure Fail(errMsg: Str255); { set theResult and quit }
		begin
			paramPtr^.returnValue := PasToZero(errMsg);
			exit(videoPlayers);
		end;

	procedure FailWithPlayers(err: str255);
		begin
			DisposHandle(thePlayers);
			Fail(err);
		end;

	procedure FailWithNames(err: str255);
		begin
			DisposHandle(theNames);
			FailWithPlayers(err);
		end;

	{$I VideoUtil.inc}

	begin
		if paramPtr^.paramCount <> 0 then Fail('parameter count is not 0');

		{ Get any HyperTalk drivers. }
		thePlayers := GetGlobal('videoHTPlayers');
		if thePlayers = nil then thePlayers := NewHandle(0)
		else
			begin
				{ Cycle thru all the names. }
				playersSize :=0;
				p := Ptr(ord4(thePlayers^)-1);
				p2 := Ptr(ord4(p)+1);
				repeat
					{ Add a short name to the player list. }
					playersSize := playersSize+1;
					p := Ptr(ord4(p)+1);
					lastChar := p^;
					{ End of item? }
					if (lastChar = ord(',')) or (lastChar = 0) then
						begin
							{ If yes, then convert it to a Pascal item in place (more or less). }
							p^ := 0;
							ZeroToPas(p2,str);
							BlockMove(@str,p2,ord4(p)-ord4(p2)+1);
							p2 := Ptr(ord4(p)+1);
						end;
				until lastChar = 0;
				if playersSize > GetHandleSize(thePlayers) then FailWithPlayers('bad videoHTPlayers global');
				SetHandleSize(thePlayers,playersSize);
			end;

		{ Add in all the XFCN drivers. }
		for i := 1 to CountResources('XFCN') do
			begin
				resHandle := GetIndResource('XFCN',i);
				GetResInfo(resHandle,resID,resType,resName);
				if length(resName) > 7 then
					if StringEqual(Copy(resName,1,7),'vidDrvr') then
						begin
							resName := Copy(resName,8,length(resName)-7);
							oldSize := GetHandleSize(thePlayers);
							SetHandleSize(thePlayers,oldSize+length(resName)+1);
							if MemError <> noErr then FailWithPlayers('out of memory');
							BlockMove(@resName,Ptr(ord4(thePlayers^)+oldSize),length(resName)+1);
						end;
			end;

		{ Now convert to the long names. }
		theNames := NewHandle(5);
		if MemError <> noErr then FailWithPlayers('out of memory');
		{ Start with a list with "None" in it. }
		str := 'None,';
		BlockMove(Ptr(ord4(@str)+1),theNames^,5);
		{ Cycle thru all the drivers available. }
		playersSize := GetHandleSize(thePlayers);
		nextNameOffset := 0;
		while nextNameOffset < playersSize do
			begin
				BlockMove(ptr(ord4(thePlayers^)+nextNameOffset),@playerXFCN,sizeOf(playerXFCN));
				if playerXFCN <> '' then
					begin
						{ Get the long name for the driver. }
						newName := Concat(EvalStr(Concat('vidDrvr',playerXFCN,'(name)')),',');
						if newName <> '' then
							begin
								oldSize := GetHandleSize(theNames);
								SetHandleSize(theNames,oldSize + length(newName));
								if MemError <> noErr then FailWithNames('out of memory');
								BlockMove(ptr(ord4(@newName)+1),ptr(ord4(theNames^)+oldSize),length(newName));
							end;
					end;
				nextNameOffset := nextNameOffset + length(playerXFCN) + 1;
			end;

		{ Now zero-terminate the names. }
		p := Ptr(ord4(theNames^)+GetHandleSize(theNames)-1);
		p^ := 0;	{ Write over the last comma. }

		{ Free the short names. }
		DisposHandle(thePlayers);

		{ Return the long name list. }
		paramPtr^.returnValue := theNames;
	end;

end.
